package com.android.systemui.ios.views;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewOutlineProvider;

public class SlideControlView extends View {

    private final RectF mBgRectF = new RectF();
    private final RectF mProgressRectF = new RectF();

    private final Point mDownPoint = new Point();
    private final Paint mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final Paint mProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private int mMax = 100;
    private int mMin = 0;
    private int mProgress = 50;
    private int mMove = 0;
    private int mChangingProgress = 50;
    private OnVolumeChangedListener mListener;

    public SlideControlView(Context context) {
        this(context, null, 0);
    }

    public SlideControlView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SlideControlView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        mBgPaint.setColor(0xa0000000);
        mProgressPaint.setColor(0xfffafafa);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        setClipToOutline(true);
        setOutlineProvider(new ViewOutlineProvider() {

            @Override
            public void getOutline(View view, Outline outline) {
                outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), view.getWidth() / 2);
            }
        });
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_F1:
                break;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {

        return super.dispatchTouchEvent(event);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mBgRectF.left = getPaddingLeft();
        mBgRectF.right = getWidth() - getPaddingRight();
        mBgRectF.top = getPaddingTop();
        mBgRectF.bottom = getHeight() - getPaddingBottom();

        mProgressRectF.set(mBgRectF);

        float stepHeight = mProgressRectF.height() / (mMax - mMin);
        if (stepHeight < 1) {
            mProgressRectF.top = mProgressRectF.bottom - mProgressRectF.bottom * mProgress / (mMax - mMin);
            mProgressRectF.top -= mMove;
            if (mProgressRectF.top < mBgRectF.top) {
                mProgressRectF.top = mBgRectF.top;
            } else if (mProgressRectF.top >= mProgressRectF.bottom) {
                mProgressRectF.top = mProgressRectF.bottom;
            }
            mChangingProgress = (int) ((mProgressRectF.bottom - mProgressRectF.top) * (mMax - mMin) / (mBgRectF.height()));
        } else {
            int moveStep = (int) (mMove / stepHeight);
            mProgressRectF.top = mProgressRectF.bottom - (mProgress + moveStep) * stepHeight;
            mChangingProgress = Math.min(mProgress + moveStep, mMax);
            if (mChangingProgress >= mMax) {
                mProgressRectF.top = mBgRectF.top;
            } else if (mChangingProgress <= mMin) {
                mProgressRectF.top = mProgressRectF.bottom;
            }
        }

        ValueAnimator animator;


        canvas.drawRect(mBgRectF, mBgPaint);
        canvas.drawRect(mProgressRectF, mProgressPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) {
            return true;
        }
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownPoint.set(x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                mMove = mDownPoint.y - y;
                if (Math.abs(mMove) >= 5) {
                    invalidate();
                    removeCallbacks(mTouchMoveRunnable);
                    postDelayed(mTouchMoveRunnable, 15);
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                mMove = 0;
                mProgress = mChangingProgress;
                break;
        }
        return true;
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        removeCallbacks(mTouchMoveRunnable);
    }

    private final Runnable mTouchMoveRunnable = new Runnable() {

        @Override
        public void run() {
            if (mListener != null) {
                mListener.onProgressChanged(mMax, mMin, Math.min(Math.max(mMin, mChangingProgress), mMax));
            }
        }
    };

    public void setMax(int max) {
        if (mMax != max) {
            mMax = max;
            invalidate();
        }
    }

    public void setMin(int min) {
        if (mMin != min) {
            mMin = min;
            invalidate();
        }
    }

    public void setProgress(int progress) {
        if (mProgress != progress) {
            mProgress = progress;
            invalidate();
        }
    }

    public void setOnVolumeChangedListener(OnVolumeChangedListener listener) {
        mListener = listener;
    }

    public interface OnVolumeChangedListener {

        void onProgressChanged(int max, int min, int progress);
    }
}
